package com.lllteam.exam.account.library

import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import androidx.core.widget.doOnTextChanged
import androidx.recyclerview.widget.LinearLayoutManager
import com.lllteam.exam.account.library.network.Repository
import com.tbruyelle.rxpermissions2.RxPermissions
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.activity_login.*
import kotlinx.android.synthetic.main.bottom_list.view.*
import java.util.concurrent.TimeUnit


class LoginActivity : AppCompatActivity() {
    companion object {
        @JvmStatic
        fun start(context: Context) {
            val starter = Intent(context, LoginActivity::class.java)
            context.startActivity(starter)
        }

        const val TAG = "LoginActivity"
    }

    private var grades = listOf(
        "一年级",
        "二年级",
        "三年级",
        "四年级",
        "五年级",
        "六年级",
        "七年级",
        "八年级",
        "九年级",
        "十年级",
        "十一年级",
        "十二年级",
        "高等教育"
    )

    private var disposable: Disposable? = null
    private var timeDisposable: Disposable? = null
    private var count = 60L

    private var account: Account? = null
    private var isChanged = true

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_login)

        val disposable = RxPermissions(this)
            .request(android.Manifest.permission.READ_PHONE_STATE)
            .subscribe {
                if (it) {
                    Log.d(TAG, "permission granted")
                    initView()
                    initListener()
                } else {
                    Log.d(TAG, "permission not granted")
                    finish()
                }
            }
    }

    private fun initListener() {
        btn_login.setOnClickListener {
            val nameCh = et_name_ch.text.toString()
            val nameEn = et_name_en.text.toString()
            val grade = et_grade.text.toString()
            val school = et_school.text.toString()
            val mobile = et_phone.text.toString()
            val code = et_code.text.toString()
            val address = et_address.text.toString()

            if (nameCh.isEmpty() || nameEn.isEmpty()) {
                showToast("姓名不能为空")
                return@setOnClickListener
            }

            if (grade.isEmpty()) {
                showToast("年级不能为空")
                return@setOnClickListener
            }

            if (mobile.isEmpty()) {
                showToast("手机号不能为空")
                return@setOnClickListener
            }

            if (code.isEmpty() && isChanged) {
                showToast("验证码不能为空")
                return@setOnClickListener
            }

            login(nameCh, nameEn, grade, mobile, code, school, address)
        }

        btn_code.setOnClickListener {
            val mobile = et_phone.text.toString()
            if (mobile.isEmpty()) {
                showToast("手机号不能为空")
                return@setOnClickListener
            }
            getVerifyCode(mobile)
        }
    }

    private fun initView() {
        val account = DataStore.getAccount(this)
        if (account != null) {
            updateUi(account)
        } else {
            getUser()
        }

        et_phone.doOnTextChanged { text, start, count, after ->
            isChanged = text.toString() != account?.mobile
            ll_code.visibility = if (isChanged) View.VISIBLE else View.GONE
        }

        et_grade.setOnFocusChangeListener { view, hasFocus ->
            if (hasFocus) {
                showActionSheet(true)
                hideKeyboard(view)
            }
        }
        et_grade.setOnClickListener {
            showActionSheet(true)
            hideKeyboard(it)
        }

        iv_back.setOnClickListener {
            finish()
        }

        tv_back.setOnClickListener {
            finish()
        }

        val linearLayoutManager = LinearLayoutManager(this)
        layout_bottom.rv_list.layoutManager = linearLayoutManager
        val adapter = ListAdapter(R.layout.bottom_list_item, grades.toMutableList())
        layout_bottom.rv_list.adapter = adapter
        adapter.setOnItemClickListener { _, _, position ->
            val grade = grades[position]
            et_grade.setText(grade)
            showActionSheet(false)
        }
        layout_bottom.tv_cancel.setOnClickListener {
            showActionSheet(false)
        }
        showActionSheet(false)
    }

    private fun updateUi(it: Account) {
        et_name_ch.setText(it.name)
        et_name_en.setText(it.enName)
        et_grade.setText(it.grade)
        et_school.setText(it.school)
        et_address.setText(it.address)
        et_phone.setText(it.mobile)

        account = it

        isChanged = false
        ll_code.visibility = if (isChanged) View.VISIBLE else View.GONE
    }

    private fun login(
        name: String,
        enName: String,
        grade: String,
        mobile: String,
        code: String,
        school: String?,
        location: String?
    ) {
        if (disposable != null && !disposable!!.isDisposed) {
            return
        }

        val sqlId = getSeqId()
        if (isChanged) {
            disposable = Repository.register(name, enName, grade, mobile, code, sqlId, school, location)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({
                    Log.d(TAG, "login success: $it")
                    if (it.success) {
                        val account = Account(
                            name,
                            enName,
                            grade,
                            mobile,
                            sqlId,
                            school ?: "",
                            location ?: ""
                        )
                        val url = DataStore.saveAccount(this, account)
                        Log.d(TAG, "save result: $url")
                        showToast(it.data.message)
                        finish()
                    } else {
                        showToast(it.data.message)
                    }
                }, {
                    Log.d(TAG, "login error: ", it)
                    showToast("保存失败")
                })
        } else {
            disposable = Repository.modifyRegister(name, enName, grade, mobile, sqlId, school, location)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({
                    Log.d(TAG, "login success: $it")
                    if (it.success) {
                        val account = Account(
                            name,
                            enName,
                            grade,
                            mobile,
                            sqlId,
                            school ?: "",
                            location ?: ""
                        )
                        val url = DataStore.saveAccount(this, account)
                        Log.d(TAG, "save result: $url")
                        showToast(it.data.message)
                        finish()
                    } else {
                        showToast(it.data.message)
                    }
                }, {
                    Log.d(TAG, "login error: ", it)
                    showToast("保存失败")
                })
        }
    }

    private fun getVerifyCode(mobile: String) {
        if (disposable != null && !disposable!!.isDisposed) {
            return
        }

        disposable = Repository.verifyCode(mobile)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({
                Log.d(TAG, "get code success: $it")
                if (it.success) {
                    showToast(it.data.message)
                    startTime()
                } else {
                    showToast(it.data.message)
                }
            }, {
                Log.d(TAG, "get code error: ", it)
                btn_code.isEnabled = true
                showToast("发送验证码失败")
            })
    }

    private fun getUser() {
        val sqlId = getSeqId()
        var disposable = Repository.getUser(sqlId)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({
                Log.d(TAG, "get user success: ${it.data}")
                val userInfo = it.data
                if (userInfo != null && userInfo.name != null && userInfo.phone != null) {
                    val account = Account(
                        userInfo.name ?: "",
                        userInfo.enName ?: "",
                        userInfo.grade ?: "",
                        userInfo.phone ?: "",
                        userInfo.seqID ?: "",
                        userInfo.school ?: "",
                        userInfo.location ?: ""
                    )
                    val url = DataStore.saveAccount(this, account)
                    Log.d(TAG, "save result: $url")
                    updateUi(account)
                }
            }, {
                Log.d(TAG, "get user error:", it)
            })
    }

    private fun startTime() {
        timeDisposable = Observable.interval(0, 1, TimeUnit.SECONDS)
            .take(count + 1)
            .map { count - it }
            .observeOn(AndroidSchedulers.mainThread())
            .doOnSubscribe {
                btn_code.isClickable = false
            }
            .doOnNext {
                btn_code.text = "剩余${it}秒"
            }
            .doOnComplete {
                btn_code.text = "获取验证码"
                btn_code.isClickable = true
            }
            .subscribe()
    }

    @RequiresApi(Build.VERSION_CODES.O)
    private fun getSeqId(): String {
        return if (RxPermissions(this).isGranted(android.Manifest.permission.READ_PHONE_STATE)) {
            try {
                Build.getSerial()
            } catch (e: Exception) {
                ""
            }
        } else {
            ""
        }
    }

    private fun showToast(text: String) {
        Toast.makeText(this, text, Toast.LENGTH_LONG).show()
    }

    private fun showActionSheet(show: Boolean) {
        layout_bottom.visibility = if (show) View.VISIBLE else View.GONE
    }

    private fun hideKeyboard(view: View) {
        val imm: InputMethodManager? = view.context
            .getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager?
        imm?.hideSoftInputFromWindow(view.windowToken, 0)
    }

    override fun onDestroy() {
        super.onDestroy()

        disposable?.dispose()
        timeDisposable?.dispose()
    }
}